# -*- coding: utf-8 -*-
"""
@Time    : 2024/6/28 16:52 
@Author  : ZhangShenao 
@File    : time_decorator.py 
@Desc    : 自定义@time装饰器,打印函数执行时间
装饰器之所以能够增强一个函数的功能,其实就是将被装饰函数用新函数替换了
虽然还是同一个函数名,但函数内部实现已经变了
而这个新函数的内部在添加了一些功能的后,还会调用之前被装饰的函数,这样就相当于对被装饰的函数做了非侵入的扩展。
"""
import datetime
import functools


def time(func):
    """自定义@time装饰器,打印函数执行时间"""

    @functools.wraps(func)  # 使用@functools.wraps装饰器,可以保留被装饰函数的元信息,如函数名,参数列表等
    def wrapper(*args, **kwargs):  # *args与**kwargs 的组合,表示可以接收一切参数
        """装饰器函数"""

        # 打印函数执行时间
        print(f'[{datetime.datetime.now()}]')

        # 将传入wrapper的参数透传给被装饰的函数,并执行被装饰的函数,返回结果
        return func(*args, **kwargs)

    # 返回装饰器函数
    # 相当于用wrapper替换了传入的函数func
    return wrapper


# 在函数上使用装饰器
@time
def say_hello(name):
    print(f'hello: {name}')


# 调用被装饰的函数
# 在被装饰器修饰后,say_hello的类型变成了function time.<locals>.wrapper
# 但是由于使用了@functools.wraps装饰器,因此say_hello的元信息可以被保留
print(say_hello)  # <function say_hello at 0x100a35940>
# name of say_hello is: say_hello, type is : <class 'function'>
print(f'name of say_hello is: {say_hello.__name__}, type is : {type(say_hello)}')
say_hello('zsa')

# 装饰器等价于如下操作:
# say_hello = time(say_hello)
